package com.ly.mpayment.rest.up.youxinya;

import com.ly.mpayment.rest.recharge.RechargeRest;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import com.ly.mpayment.core.secuity.MD5;
import com.ly.mpayment.core.util.Config;
import com.ly.mpayment.core.util.DateUtils;
import com.ly.mpayment.core.util.HttpClient;
import com.ly.mpayment.core.util.JsonUtils;
import com.ly.mpayment.core.util.StringUtils;
import com.ly.mpayment.persist.entity.UpOrder;
import com.ly.mpayment.persist.entity.UpShopInfo;
import com.ly.mpayment.persist.service.downrechargeflow.IDownRechargeFlowService;
import com.ly.mpayment.persist.service.downshopinfo.IDownShopInfoService;
import com.ly.mpayment.persist.service.uporder.IUporderService;
import com.ly.mpayment.persist.service.upshopinfo.IUpShopInfoService;

import net.sf.json.JSONObject;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import java.util.HashMap;
import java.util.Map;

@Component
@Path("youxinya")
public class YouXinYaRest {
    Logger logger = Logger.getLogger(YouXinYaRest.class);

    @Autowired
    IUporderService upOrderService;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Autowired
    IDownRechargeFlowService flowService;

    @Autowired
    IDownShopInfoService shopService;

    @Autowired
    IUpShopInfoService upShopInfoService;

	@Path("callBack")
	@GET
	public synchronized String callBack(@QueryParam("userId") String userId,@QueryParam("orderId") String orderId
			,@QueryParam("serialno") String serialno ,@QueryParam("orderStatus") String orderStatus  ,@QueryParam("sign") String sign
			,@QueryParam("errDesc") String errDesc ){

		logger.info("youxinya_callback:userId"+userId+",orderId:"+orderId+",orderStatus:"+orderStatus+",sign:"+sign+",serialno:"+serialno);

		UpOrder order = upOrderService.findById(serialno);

		if(order == null){
			logger.info("订单不存在:"+serialno);
			return "订单不存在";
		}
		final UpShopInfo upShopInfo = this.upShopInfoService.findByUserId(order.getUserOrder().getUseruuid());
		if(upShopInfo == null){
			logger.info("渠道用户不存在:"+serialno);
			return "failt";
		}
		//		签名(MD5)。
		//		sign=MD5(orderId orderStatus serialno userId privateKey)。各个值之间无空格。
		String sg = MD5.md5(orderId+orderStatus+serialno+userId+upShopInfo.getUpkey());
		if(!StringUtils.isBlank(serialno) && !StringUtils.isBlank(orderId) && sign.equals(sg)){
//			0	充值成功。话费已实际充入最终用户手机号
//			1	等待处理
//			2	处理中
//			3	失败
			if (order != null && orderStatus.equals("0") && order.getStatus() == Config.status[0]) {
				order.setRemark( errDesc != null ? errDesc : "");
				RechargeRest.successUpOrder.add(order);
				return createResponse("success","00").asXML();
			}else if(order != null && order.getStatus() == Config.status[0] && orderStatus.equals("3")){
				order.setRemark(errDesc != null ? errDesc : "");
				RechargeRest.failtUpOrder.add(order);
				return createResponse("success","00").asXML();
			}else{
				logger.info("youxinya_not_found_order:" + serialno +","+order.getUpphonenum());
			}
		}else {
			logger.info("签名错误:"+sign+",+"+sg);
		}
		return createResponse("failt","01").asXML();
	}

	private static Document createResponse(String status,String code){
		Document root = DocumentHelper.createDocument();
		Element request = root.addElement("Response");
		Element statusXml = DocumentHelper.createElement("status");
		statusXml.addText(status);
		Element codeXml = DocumentHelper.createElement("code");
		codeXml.addText(code);
		request.add(statusXml);
		request.add(codeXml);

		return root;
	}

    /**
     * 订单提交
     *
     * @param order
     * @param shop
     */
	public void commitOrder(UpOrder order, UpShopInfo shop) {

		String temp [] = order.getUpShopPro().getProductCode().split("\\|");
		StringBuilder sb = new StringBuilder();
		sb.append("userId=");
		//一个省份一个编码 从产品编码配置处获取
		sb.append(temp[1]);
		sb.append("&productId=");
		sb.append(temp[0]);
		sb.append("&mobile=");
		sb.append(order.getUpphonenum());
		sb.append("&serialno=");
		sb.append(order.getUporderuuid());
		sb.append("&dtCreate=");
		String doCreate = new DateUtils().toTimeStamp();
		sb.append(doCreate);
//		签名(MD5)。 sign=MD5(dtCreate mobile productId serialno  userId privateKey)。各个值之间无空格。
		StringBuilder sign = new StringBuilder();

		sign.append(doCreate).append(order.getUpphonenum()).append(temp[0]).append(order.getUporderuuid()).append(temp[1]).append(shop.getUpkey());

		sb.append("&sign=");
		sb.append(MD5.md5(sign.toString()));

//		<?xml version="1.0" encoding="UTF-8" ?><response><status>success</status><code>00</code><orderId>1587822437333106</orderId><serialno>2c922ab7717e5a890171b05ecfb30010</serialno></response>
		String result = HttpClient.httpGetUrl(shop.getOrderCommitAddress().concat("?").concat(sb.toString()));
		logger.info("youxiya_result:"+result+","+order.getUpphonenum()+",:"+sb.toString());
		JSONObject json = JsonUtils.getJSONOBJCT();
		try {
			JsonUtils.iterateNodes(DocumentHelper.parseText(result).getRootElement(), json);
			JSONObject res = json.getJSONObject("response");
			//提交成功
			if( res.containsKey("code") && res.getString("code").equals("00")) {
				upOrderService.updateUpOrderMsg(order, res.getString("orderId"), res.containsKey("errDesc") ? res.getString("errDesc") : res.getString("status"));
			}else if(res.containsKey("code") && (res.getString("code").equals("31") ||  res.getString("code").equals("50"))) {
				//保留
				upOrderService.updateUpOrderArtificial(order,"",res.containsKey("errDesc") ? res.getString("errDesc") : "提单失败,人工");
			}else if(res.containsKey("code") && (
					res.getString("code").equals("9") ||
					res.getString("code").equals("10") ||
					res.getString("code").equals("11") ||
					res.getString("code").equals("12") ||
					res.getString("code").equals("20") ||
					res.getString("code").equals("22") ||
					res.getString("code").equals("23") ||
					res.getString("code").equals("25") ||
					res.getString("code").equals("28") ||
					res.getString("code").equals("30") ||
					res.getString("code").equals("40") ||
					res.getString("code").equals("41") ||
					res.getString("code").equals("42") ||
					res.getString("code").equals("43") ||
					res.getString("code").equals("44") ||
					res.getString("code").equals("51") ||
					res.getString("code").equals("61")
					)){
				order.setRemark( res.getString("errDesc"));
				RechargeRest.failtUpOrder.add(order);
			}else {
				upOrderService.updateUpOrderArtificial(order,"",res.containsKey("errDesc") ? res.getString("errDesc") : "人工");
			}
		} catch (DocumentException e) {
			e.printStackTrace();
			logger.info(e.getMessage());
		}
	}

	/**
	 *  订单查询
	 * @param upOrder
	 * @param shopInfo
	 */
	public void queryOrder(UpOrder upOrder, UpShopInfo shopInfo) {
		upOrder = this.upOrderService.findByShopId(upOrder.getUporderuuid());

		String temp [] = upOrder.getUpShopPro().getProductCode().split("\\|");
		StringBuilder sb = new StringBuilder();
		sb.append("userId=");
		sb.append(temp[1]);
		sb.append("&serialno=");
		sb.append(upOrder.getUporderuuid());
		sb.append("&sign=");
		sb.append(MD5.md5(upOrder.getUporderuuid()+temp[1]+shopInfo.getUpkey()));
//		签名(MD5)。 sign=MD5(serialno userId privateKey)。各个值之间无空格。
		logger.info("youxinya_queryOrder:"+sb.toString());

		String result = HttpClient.httpGetUrl(shopInfo.getOrderStatusAddress().concat("?").concat(sb.toString()));
		JSONObject json = JsonUtils.getJSONOBJCT();
		try {
			JsonUtils.iterateNodes(DocumentHelper.parseText(result).getRootElement(), json);
			logger.info("youxinya_result:"+json.toString()+","+upOrder.getUpphonenum());
			//充值成功
			if(json.getJSONObject("response").containsKey("code") && json.getJSONObject("response").getString("code").equals("00") && json.getJSONObject("response").getJSONObject("data").getString("orderStatus").equals("0")) {
				upOrder.setRemark( json.getJSONObject("response").containsKey("errDesc") ? json.getJSONObject("response").getString("errDesc") :  json.getJSONObject("response").getString("status"));
				RechargeRest.successUpOrder.add(upOrder);
			}else if(json.getJSONObject("response").containsKey("code") && json.getJSONObject("response").getString("code").equals("00")
					&& json.getJSONObject("response").getJSONObject("data").getString("orderStatus").equals("3") ) {
				upOrder.setRemark(json.getJSONObject("response").getString("errDesc"));
				RechargeRest.failtUpOrder.add(upOrder);
			}else if(json.getJSONObject("response").containsKey("code") && (
					json.getJSONObject("response").getString("code").equals("9") ||
							json.getJSONObject("response").getString("code").equals("10") ||
							json.getJSONObject("response").getString("code").equals("11") ||
							json.getJSONObject("response").getString("code").equals("12") ||
							json.getJSONObject("response").getString("code").equals("20") ||
							json.getJSONObject("response").getString("code").equals("22") ||
							json.getJSONObject("response").getString("code").equals("23") ||
							json.getJSONObject("response").getString("code").equals("25") ||
							json.getJSONObject("response").getString("code").equals("28") ||
							json.getJSONObject("response").getString("code").equals("30") ||
							json.getJSONObject("response").getString("code").equals("40") ||
							json.getJSONObject("response").getString("code").equals("41") ||
							json.getJSONObject("response").getString("code").equals("42") ||
							json.getJSONObject("response").getString("code").equals("43") ||
							json.getJSONObject("response").getString("code").equals("44") ||
							json.getJSONObject("response").getString("code").equals("51") ||
							json.getJSONObject("response").getString("code").equals("61")
			)) {
				upOrder.setRemark(json.getJSONObject("response").getString("status"));
				RechargeRest.failtUpOrder.add(upOrder);
			}else {
				this.upOrderService.addOrderMsg(upOrder, json.getJSONObject("response").getString("status"));
			}
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}

}
